package com.xyy.ec.qualification.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSON;
import com.xyy.ec.qualification.enums.DBTypeEnum;
import com.xyy.ec.qualification.pojo.DataSource;
import com.xyy.ec.qualification.pojo.DataSourceConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import java.sql.SQLException;
import java.util.Objects;
import java.util.Properties;
@Slf4j
public class DBUtil {
    private static final Logger logger = LoggerFactory.getLogger(DBUtil.class);


    /**
     * 初始化连接池
     *
     * @param ds
     * @return
     */
    public static DruidDataSource init(DataSource ds, Boolean autoReconnect) {
        // 1.参数校验
        DataSource.check(ds);
        // 2.初始化
        return init0(DBTypeEnum.getDriver(ds.getDbType()), ds.getUrl(), ds.getUserName(), ds.getPassword(), autoReconnect);
    }

    public static DruidDataSource init(DataSourceConfig ds, Boolean autoReconnect) {
        DataSource dataSource = trans(ds);
        boolean success = ConnectDB.testConnection(dataSource);
        if (!success) {
            throw new RuntimeException("测试数据库连接异常");
        }
        return init0(DBTypeEnum.getDriver(dataSource.getDbType()), dataSource.getUrl(), dataSource.getUserName(), dataSource.getPassword(), autoReconnect);
    }

    private static DataSource trans(DataSourceConfig ds) {

        DataSource dataSource = new DataSource();
        String url = "";
        String dbType = "";
        if (Objects.equals("2", ds.getBdType())) {
            dbType = DBTypeEnum.MYSQL.getDbType();
            url = String.format("jdbc:mysql://%s:%s/%s", ds.getHost(), ds.getPort(), ds.getDbName());
            dataSource.setUrl(url);
        } else if (Objects.equals("3", ds.getBdType())) {
            dbType = DBTypeEnum.ORACLE.getDbType();
            url = String.format("jdbc:oracle:thin:@%s:%s:%s", ds.getHost(), ds.getPort(), ds.getDbName());
            dataSource.setUrl(url);
        } else if (Objects.equals("1", ds.getBdType())) {
            dbType = DBTypeEnum.SQL_SERVER.getDbType();
            StringBuilder sb = new StringBuilder("jdbc:sqlserver://%s:%s;DatabaseName=%s;");
            if (StringUtils.isBlank(ds.getUserName()) && StringUtils.isBlank(ds.getUserPass())) {
                sb.append("integratedSecurity=true");
            }
            //url = String.format("jdbc:sqlserver://%s:%s;DatabaseName=%s", ds.getHost(), ds.getPort(), ds.getDbName());
            url = String.format(sb.toString(), ds.getHost(), ds.getPort(), ds.getDbName());
            dataSource.setUrl(url);
        } else if (Objects.equals("4", ds.getBdType())) {
            dbType = DBTypeEnum.SQL_SERVER_V2000.getDbType();
            StringBuilder sb = new StringBuilder("jdbc:jtds:sqlserver://%s:%s;DatabaseName=%s;");
            if (StringUtils.isBlank(ds.getUserName()) && StringUtils.isBlank(ds.getUserPass())) {
                sb.append("integratedSecurity=true");
            }
            url = String.format(sb.toString(), ds.getHost(), ds.getPort(), ds.getDbName());
            //url = String.format("jdbc:jtds:sqlserver://%s:%s;DatabaseName=%s", ds.getHost(), ds.getPort(), ds.getDbName());
            dataSource.setUrl(url);
        } else if (Objects.equals("5", ds.getBdType())) {
            dbType = DBTypeEnum.ORACLE_9I.getDbType();
            url = String.format("jdbc:oracle:thin:@%s:%s/%s", ds.getHost(), ds.getPort(), ds.getDbName());
            dataSource.setUrl(url);
        }

        dataSource.setUserName(ds.getUserName());
        dataSource.setPassword(ds.getUserPass());
        dataSource.setDbType(dbType);
        DataSource.check(dataSource);
        logger.info("数据库配置信息：{}", JSON.toJSONString(dataSource));
        return dataSource;
    }


    /**
     * 初始化连接池
     *
     * @param driver
     * @param url
     * @param userName
     * @param password
     * @return
     */
    private static DruidDataSource init0(String driver, String url, String userName, String password, Boolean autoReconnect) {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        ds.setInitialSize(1);
        ds.setMinIdle(1);
        ds.setMaxActive(50);
        ds.setMaxWait(60000);
        ds.setTestOnBorrow(true);
        ds.setTestWhileIdle(true);
        Properties properties = new Properties();
        if (autoReconnect) {
            properties.put("autoReconnect", "true");
        }
        properties.put("connectTimeout", "60000");
        properties.put("socketTimeout", "120000");
        ds.setConnectProperties(properties);
        ds.setTimeBetweenEvictionRunsMillis(60000);
        ds.setMinEvictableIdleTimeMillis(300000);
        //数据库连接超时强制回收
        ds.setRemoveAbandoned(true);
        ds.setRemoveAbandonedTimeout(600);
        ds.setLogAbandoned(true);
        if (DBTypeEnum.ORACLE.getDriver().equals(driver) || DBTypeEnum.ORACLE_9I.getDriver().equals(driver)) {
            // oracle查询特殊处理
            ds.setValidationQuery("select 1 FROM DUAL");
        } else {
            ds.setValidationQuery("select 1");
        }
        try {
            ds.init();
        } catch (SQLException e) {
            logger.info("ds={}", JSON.toJSONString(ds), e);
            ds.close();
            throw new RuntimeException(e.getMessage(), e);
        } catch (Exception e) {
            logger.info("ds={}", JSON.toJSONString(ds), e);
            ds.close();
            throw new RuntimeException(e.getMessage(), e);
        } catch (Throwable e) {
            logger.info("ds={}", JSON.toJSONString(ds), e);
            ds.close();
            throw new RuntimeException(e.getMessage(), e);
        }

        return ds;
    }
}
